package com.csii.activiti.server.core.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.csii.activiti.server.abstraction.entity.ActDept;
import com.csii.activiti.server.abstraction.entity.ActRole;
import com.csii.activiti.server.abstraction.entity.ActUser;
import com.csii.activiti.server.abstraction.entity.ActUserDetail;
import com.csii.activiti.server.abstraction.service.ActBasicService;
import com.csii.activiti.server.abstraction.service.ActDeptService;
import com.csii.activiti.server.abstraction.service.ActRoleService;
import com.csii.activiti.server.abstraction.service.ActUserService;
import com.csii.activiti.server.core.constant.*;
import com.csii.activiti.server.core.entity.*;
import com.csii.activiti.server.core.entity.db.*;
import com.csii.activiti.server.core.exception.RequestParamException;
import com.csii.activiti.server.core.mapper.*;
import com.csii.activiti.server.core.query.*;
import com.csii.activiti.server.core.service.FlowGroupService;
import com.csii.activiti.server.core.service.FlowQueryService;
import com.csii.activiti.server.core.utils.BasicCommonUtils;
import com.csii.activiti.server.core.utils.ELUtils;
import com.csii.activiti.server.core.utils.FormDataPermissionUtils;
import com.csii.activiti.server.core.utils.VerifyConditionUtils;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.*;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
public class FlowQueryServiceImpl implements FlowQueryService {

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private ActBasicService actBasicService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private HistoryService historyService;

    @Autowired
    private ActExtensionMapper actExtensionMapper;

    @Autowired
    private ActFlowFormMapper actFlowFormMapper;

    @Autowired
    private ActUserService actUserService;

    @Autowired
    private ActFlowNodeMapper actFlowNodeMapper;

    @Autowired
    private ActFlowDelegateTaskMapper actFlowDelegateTaskMapper;

    @Autowired
    private FlowGroupService flowGroupService;

    @Autowired
    private ActFlowConfigurationMapper actFlowConfigurationMapper;

    @Autowired
    private ActFlowPermissionMapper actFlowPermissionMapper;

    @Autowired
    private ActRoleService actRoleService;

    @Autowired
    private ActDeptService actDeptService;

    @Autowired
    private ActFlowPublishConfigurationMapper actFlowPublishConfigurationMapper;

    @Autowired
    private ActFlowPeopleWhoCopiedMapper actFlowPeopleWhoCopiedMapper;

    @Autowired
    private ActFlowNodeKeyMapper actFlowNodeKeyMapper;

    @Autowired
    private ActFlowRegisterMapper flowRegisterMapper;

    private final String exclusiveGateway = "exclusiveGateway";

    @Override
    public Page<ActFlowDefinition> queryApplyFlowList(QueryActFlowDefinition queryActFlowDefinition, Page page) {
        String currentTenantId = actBasicService.getCurrentTenantId();
        ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery().latestVersion();
        processDefinitionQuery.processDefinitionTenantId(currentTenantId);
        //设置查询条件
        if (queryActFlowDefinition.getName() != null){
            processDefinitionQuery.processDefinitionNameLike("%"+queryActFlowDefinition.getName()+"%");
        }
        if (queryActFlowDefinition.getKey() != null){
            processDefinitionQuery.processDefinitionKey(queryActFlowDefinition.getKey());
        }

        List<ProcessDefinition> processDefinitionList = processDefinitionQuery.listPage((int) ((page.getCurrent() - 1) * page.getSize()), (int) page.getSize());
        long total = processDefinitionQuery.count();
        List<ActFlowDefinition> actFlowDefinitionList = processDefinitionList.stream().map(processDefinition ->
                new ActFlowDefinition(processDefinition.getId(), processDefinition.getName(), processDefinition.getKey(), processDefinition.getVersion())).collect(Collectors.toList());
        //DOTO 配置权限
        Page<ActFlowDefinition> resultPage = new Page<>();
        resultPage.setRecords(actFlowDefinitionList);
        resultPage.setTotal(total);
        return resultPage;
    }

    @Override
    public List<ActFlowGroup> queryMaintainFlowList(boolean selectFlowDefinition) {
        String currentTenantId = actBasicService.getCurrentTenantId();
        LambdaQueryWrapper<ActFlowConfigurationEntity> wrapper = new LambdaQueryWrapper<ActFlowConfigurationEntity>()
                .orderByAsc(ActFlowConfigurationEntity::getSort)
                .select(ActFlowConfigurationEntity::getId,ActFlowConfigurationEntity::getLastDeploymentId, ActFlowConfigurationEntity::getFlowKey, ActFlowConfigurationEntity::getFlowName, ActFlowConfigurationEntity::getGroupId, ActFlowConfigurationEntity::getDescription
                        ,ActFlowConfigurationEntity::getPublish, ActFlowConfigurationEntity::getIconType, ActFlowConfigurationEntity::getLastUpdateTime, ActFlowConfigurationEntity::getSort, ActFlowConfigurationEntity::getStatus);
        final Map<String, List<String>> flowIdAndPermissionValue = new HashMap<>();
        wrapper.eq(ActFlowConfigurationEntity::getActTenantId,currentTenantId);
        if (selectFlowDefinition){
            //查询已经发布的流程
            wrapper.eq(ActFlowConfigurationEntity::getPublish,true);
            //查询表单模式的流程
            wrapper.eq(ActFlowConfigurationEntity::getPattern,ApprovalConfigConstant.PATTERN_FORM);
            //查询申请需要添加权限
            ActUserDetail currentLoginUser = actBasicService.getCurrentLoginUser();
            Set<String> permissionValueList = new HashSet<>();
            permissionValueList.add("all");
            permissionValueList.add(currentLoginUser.getUsername());
            if (CollUtil.isNotEmpty(currentLoginUser.getDeptCodes())){
                permissionValueList.addAll(currentLoginUser.getDeptCodes());
            }
            if (CollUtil.isNotEmpty(currentLoginUser.getRoleCodes())){
                permissionValueList.addAll(currentLoginUser.getRoleCodes());
            }
            List<ActFlowPermissionEntity> myPermissionList = actFlowPermissionMapper.selectList(new LambdaQueryWrapper<ActFlowPermissionEntity>().select(ActFlowPermissionEntity::getFlowId).groupBy(ActFlowPermissionEntity::getFlowId).in(ActFlowPermissionEntity::getPermissionValue, permissionValueList));
            //没有权限
            if (CollUtil.isEmpty(myPermissionList)){
                return new ArrayList<>();
            }
            List<String> flowIds = myPermissionList.stream().map(ActFlowPermissionEntity::getFlowId).collect(Collectors.toList());
            wrapper.in(ActFlowConfigurationEntity::getId,flowIds);
        }else{
            List<ActFlowPermissionEntity> permissionList = actFlowPermissionMapper.selectList(new LambdaQueryWrapper<ActFlowPermissionEntity>().orderByAsc(ActFlowPermissionEntity::getId));
            Map<String, Set<String>> typeAndPermissionValue = permissionList.stream().collect(Collectors.groupingBy(ActFlowPermissionEntity::getPermissionType,Collectors.mapping(item->item.getPermissionValue(),Collectors.toSet())));
            Map<String,String> translationMap = new HashMap();
            translationMap.put(ActFlowPermissionConstant.USER + "all","所有成员");
            //查询部门
            Set<String> deptCodes = typeAndPermissionValue.get(ActFlowPermissionConstant.DEPT);
            if (CollUtil.isNotEmpty(deptCodes)){
                List<ActDept> deptList = actDeptService.queryDeptByDeptCodes(deptCodes);
                if (CollUtil.isNotEmpty(deptList)){
                    translationMap.putAll(deptList.stream().collect(Collectors.toMap(item -> ActFlowPermissionConstant.DEPT + item.getDeptCode(), ActDept::getDeptName, (v1, v2) -> v2)));
                }
            }
            //查询角色
            Set<String> roleCodes = typeAndPermissionValue.get(ActFlowPermissionConstant.ROLE);
            if (CollUtil.isNotEmpty(roleCodes)){
                List<ActRole> roleList = actRoleService.queryRoleByRoleCodes(roleCodes);
                if (CollUtil.isNotEmpty(roleList)){
                    translationMap.putAll(roleList.stream().collect(Collectors.toMap(item -> ActFlowPermissionConstant.ROLE + item.getRoleCode(), ActRole::getRoleName, (v1, v2) -> v2)));
                }
            }

            //查询人员
            Set<String> usernames = typeAndPermissionValue.get(ActFlowPermissionConstant.USER);
            if (CollUtil.isNotEmpty(usernames)){
                List<ActUser> userList = actUserService.queryUserByUsernames(usernames);
                if (CollUtil.isNotEmpty(userList)){
                    translationMap.putAll(userList.stream().collect(Collectors.toMap(item -> ActFlowPermissionConstant.USER + item.getUsername(), ActUser::getNickname, (v1, v2) -> v2)));
                }
            }
            flowIdAndPermissionValue.putAll(permissionList.stream().collect(Collectors.groupingBy(ActFlowPermissionEntity::getFlowId,Collectors.mapping(item->translationMap.get(item.getPermissionType()+item.getPermissionValue()),Collectors.toList()))));

        }
        List<ActFlowConfigurationEntity> actFlowConfigurationEntityList = actFlowConfigurationMapper.selectList(wrapper);

        Map<String, List<ActFlowConfiguration>> groupIdAndFlowMap = new HashMap<>();
        if (CollUtil.isNotEmpty(actFlowConfigurationEntityList)){
            Map<String, ActFlowPublishConfigEntity> deploymentIdAndEntity = null;
            if (selectFlowDefinition){
                Set<String> deploymentIds = actFlowConfigurationEntityList.stream().map(ActFlowConfigurationEntity::getLastDeploymentId).collect(Collectors.toSet());
                List<ActFlowPublishConfigEntity> configurationList = actFlowPublishConfigurationMapper.selectList(new LambdaQueryWrapper<ActFlowPublishConfigEntity>().select(ActFlowPublishConfigEntity::getId, ActFlowPublishConfigEntity::getIconType, ActFlowPublishConfigEntity::getDescription, ActFlowPublishConfigEntity::getFlowKey, ActFlowPublishConfigEntity::getFlowName).in(ActFlowPublishConfigEntity::getId, deploymentIds));
                deploymentIdAndEntity = configurationList.stream().collect(Collectors.toMap(ActFlowPublishConfigEntity::getId, item->item, (k1, k2) -> k2));
            }
            Map<String, ActFlowPublishConfigEntity> deploymentIdAndPublishConfigurationEntity = deploymentIdAndEntity;

                groupIdAndFlowMap = actFlowConfigurationEntityList.stream().collect(Collectors.groupingBy(ActFlowConfigurationEntity::getGroupId, Collectors.mapping(item -> {
                    ActFlowConfiguration actFlowConfiguration = new ActFlowConfiguration();
                    actFlowConfiguration.setId(item.getId());
                    actFlowConfiguration.setGroupId(item.getGroupId());
                    actFlowConfiguration.setLastUpdateTime(item.getLastUpdateTime());
                    actFlowConfiguration.setSort(item.getSort());
                    actFlowConfiguration.setStatus(item.getStatus());
                    if (selectFlowDefinition){
                        ActFlowPublishConfigEntity entity = deploymentIdAndPublishConfigurationEntity.get(item.getLastDeploymentId());
                        actFlowConfiguration.setFlowKey(entity.getFlowKey());
                        actFlowConfiguration.setFlowName(entity.getFlowName());
                        actFlowConfiguration.setDescription(entity.getDescription());
                        actFlowConfiguration.setIconType(entity.getIconType());
                    }else{
                        actFlowConfiguration.setPublish(item.getPublish());
                        actFlowConfiguration.setFlowKey(item.getFlowKey());
                        actFlowConfiguration.setFlowName(item.getFlowName());
                        actFlowConfiguration.setDescription(item.getDescription());
                        actFlowConfiguration.setIconType(item.getIconType());
                        //设置权限
                        List<String> permissions = flowIdAndPermissionValue.get(item.getId());
                        if (CollUtil.isNotEmpty(permissions)){
                            //过滤null值
                            permissions = permissions.stream().filter(val->val != null).collect(Collectors.toList());
                            if (!permissions.isEmpty()){
                                actFlowConfiguration.setPermissionList(permissions);
                            }
                        }
                    }
                    return actFlowConfiguration;
            }, Collectors.toList())));
        }
        final Map<String, List<ActFlowConfiguration>> groupIdAndFlowMapFinal = groupIdAndFlowMap;
        List<ActFlowGroupEntity> actFlowGroupEntityList = flowGroupService.queryActFlowGroupList();
        return actFlowGroupEntityList.stream().filter(item-> !selectFlowDefinition || groupIdAndFlowMapFinal.get(item.getId()) != null).map(item-> new ActFlowGroup(item.getId(),item.getGroupName(),groupIdAndFlowMapFinal.get(item.getId()))).collect(Collectors.toList());

    }

    @Override
    public Page<ActFlowTodo> queryTodoList(QueryActFlowTodo queryActFlowTodo, Page page,String assignee) {
        String currentTenantId = actBasicService.getCurrentTenantId();
        if (StrUtil.isNotBlank(queryActFlowTodo.getProcessName())){
            queryActFlowTodo.setProcessName("%"+queryActFlowTodo.getProcessName()+"%");
        }

        if (assignee == null && !(queryActFlowTodo instanceof QueryActFlowTask)){
            ActUserDetail currentLoginUser = actBasicService.getCurrentLoginUser();
            assignee = currentLoginUser.getUsername();
        }
        Page<ActFlowTodo> resultPage = actExtensionMapper.queryTodoList(page,assignee, queryActFlowTodo,currentTenantId);
        List<ActFlowTodo> todoList = resultPage.getRecords();
        if (CollUtil.isEmpty(todoList)){
            return resultPage;
        }
        //resultPage.setTotal(actExtensionMapper.queryTodoCount(assignee,queryActFlowTodo));
        Set<String> deploymentIds = new HashSet<>();
        Set<String> usernames = new HashSet<>();
        Set<String> nodeIds = new HashSet<>();
        for (ActFlowTodo actFlowTodo : todoList) {
            usernames.add(actFlowTodo.getApplyer());
            usernames.add(actFlowTodo.getApprovalUser());
            deploymentIds.add(actFlowTodo.getDeploymentId());
            nodeIds.add(actFlowTodo.getNodeId());
        }
        Map<String, ActFlowPublishConfigEntity> deploymentIdAndPublishMap = queryDeploymentIdAndPublishMap(deploymentIds);
        List<ActUser> actUsers = actUserService.queryUserByUsernames(usernames);

        Set<String> processInstanceIds = todoList.stream().map(ActFlowTodo::getProcessInstanceId).collect(Collectors.toSet());
        Map<String, Map<String, Object>> processInstanceIdAndFormData = null;
        Map<String, ActFlowNode> nodeIdAndNodeMap = null;

        processInstanceIdAndFormData = queryVariableByExecutionId(processInstanceIds);
        List<ActFlowNodeEntity> actFlowNodeEntities = actFlowNodeMapper.selectBatchIds(nodeIds);
        if (CollUtil.isNotEmpty(actFlowNodeEntities)){
            nodeIdAndNodeMap = actFlowNodeEntities.stream().collect(Collectors.toMap(ActFlowNodeEntity::getId, item -> item.transitionActFlowNode()));
        }

        if (CollUtil.isNotEmpty(actUsers)){
            Map<String, String> usernameAndNickname = actUsers.stream().collect(Collectors.toMap(ActUser::getUsername, ActUser::getNickname, (k1, k2) -> k2));
            for (ActFlowTodo actFlowTodo : todoList) {
                actFlowTodo.setApplyer(usernameAndNickname.get(actFlowTodo.getApplyer()));
                actFlowTodo.setApprovalUser(usernameAndNickname.get(actFlowTodo.getApprovalUser()));
                ActFlowPublishConfigEntity publishConfig = deploymentIdAndPublishMap.get(actFlowTodo.getDeploymentId());
                if(publishConfig != null){
                    actFlowTodo.setIconType(publishConfig.getIconType());
                }
                ActFlowConfigurationItem configurationItem = nodeIdAndNodeMap.get(actFlowTodo.getNodeId()).getConfigurationItem();

                actFlowTodo.setActionSetting(configurationItem.getActionSetting());
                //设置表单数据
                if (processInstanceIdAndFormData != null){
                    Map<String, Object> formData = processInstanceIdAndFormData.get(actFlowTodo.getProcessInstanceId());
                    FormDataPermissionUtils.processFormDataPermission(formData,configurationItem.getFormContentSetting());
                    //是否需要表单数据
                    if (queryActFlowTodo.isNeedFormData()){
                        actFlowTodo.setFormData(formData);
                    }
                    if (publishConfig != null){
                        String summary = ELUtils.getSummary(publishConfig.getSummary(),publishConfig.getManyConditionJson(),formData);
                        actFlowTodo.setSummary(summary);
                    }
                }
            }
        }
        return resultPage;
    }


    @Override
    public ActFlowDetail queryFlowDetail(String id) {
        //判断是不是任务ID
        HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().taskId(id).singleResult();
        String username = actBasicService.getCurrentLoginUser().getUsername();
        HistoricProcessInstance historicProcessInstance = null;
        if (historicTaskInstance == null){
            historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(id).singleResult();
            HistoricTaskInstanceQuery historicTaskInstanceQuery = historyService.createHistoricTaskInstanceQuery().processInstanceId(id);
            if (!username.equals(historicProcessInstance.getStartUserId())){
                historicTaskInstanceQuery.taskAssignee(username);
            }
            List<HistoricTaskInstance> list = historicTaskInstanceQuery.orderByHistoricTaskInstanceStartTime().desc().listPage(0,1);
            if (CollUtil.isEmpty(list)){
                throw new RequestParamException("已转交或者没有权限查看此任务");
            }
            historicTaskInstance = list.get(0);
        }
        if (historicProcessInstance == null){
            historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(historicTaskInstance.getProcessInstanceId()).singleResult();
        }
        ActFlowNode actFlowNode = actFlowNodeMapper.selectById(historicTaskInstance.getTaskDefinitionKey()).transitionActFlowNode();
        ActFlowDetail actFlowDetail = buildActFlowDetail(historicTaskInstance.getProcessInstanceId(), historicProcessInstance.getDeploymentId(), actFlowNode.getConfigurationItem().getFormContentSetting(), actFlowNode.getConfigurationItem().getActionSetting());
        actFlowDetail.setTaskId(historicTaskInstance.getId());
        actFlowDetail.setDigitalSignature(actFlowNode.getConfigurationItem().isDigitalSignature());
        actFlowDetail.setStartTime(historicProcessInstance.getStartTime());
        actFlowDetail.setDeploymentId(historicProcessInstance.getDeploymentId());
        actFlowDetail.setInitiator(queryUsernameAndNickname(CollUtil.newHashSet(historicProcessInstance.getStartUserId())).get(historicProcessInstance.getStartUserId()));
        actFlowDetail.setFlowKey(historicProcessInstance.getProcessDefinitionKey());
        if (historicTaskInstance.getEndTime() != null || !historicTaskInstance.getAssignee().equals(username)) {
            actFlowDetail.setActionSetting(new ArrayList<>());
            List<ActFlowFormContentSetting> formPermissionSettings = actFlowDetail.getFormPermissionSettings();
            if (formPermissionSettings != null){
                //解决第一个节点全是可编辑的状态，从消息节点进入审批时流程已经通过，表单的却可以编辑的问题
                for (ActFlowFormContentSetting formPermissionSetting : formPermissionSettings) {
                    if (FlowFormContentSettingConstant.EDIT.equals(formPermissionSetting.getSetting())) {
                        formPermissionSetting.setSetting(FlowFormContentSettingConstant.READ);
                    }
                }
            }
        }
        return actFlowDetail;
    }

    @Override
    public ActFlowDetail queryMyApplyFlowDetail(String processInstanceId) {
        return buildMyApplyFlowDetail(processInstanceId,true);
    }

    private ActFlowDetail buildMyApplyFlowDetail(String processInstanceId,boolean selectHistoryRecordFlag) {
        HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        ActFlowNodeEntity actFlowNodeEntity = actFlowNodeMapper.selectById(historicProcessInstance.getDeploymentId());
        List<ActFlowFormContentSetting> actFlowFormContentSettings = null;
        if (actFlowNodeEntity != null){
            actFlowFormContentSettings = actFlowNodeEntity.transitionActFlowFormContentSettingList();
        }
        ActFlowDetail actFlowDetail = buildActFlowDetail(processInstanceId, historicProcessInstance.getDeploymentId(), actFlowFormContentSettings, null,selectHistoryRecordFlag);
        actFlowDetail.setStartTime(historicProcessInstance.getStartTime());
        actFlowDetail.setInitiator(queryUsernameAndNickname(CollUtil.newHashSet(historicProcessInstance.getStartUserId())).get(historicProcessInstance.getStartUserId()));
        actFlowDetail.setDeploymentId(historicProcessInstance.getDeploymentId());
        actFlowDetail.setFlowKey(historicProcessInstance.getProcessDefinitionKey());

        return actFlowDetail;
    }


    private ActFlowDetail buildActFlowDetail(String processInstanceId,String deploymentId,List<ActFlowFormContentSetting> formContentSetting, List<ActFlowActionSetting> actionSetting,boolean selectHistoryRecordFlag){
        ActFlowDetail actFlowDetail = new ActFlowDetail();
        actFlowDetail.setProcessInstanceId(processInstanceId);
        if (selectHistoryRecordFlag){
            ActFlowRegisterEntity actFlowRegisterEntity = flowRegisterMapper.selectById(processInstanceId);
            actFlowDetail.setHasHistoryRecord(actFlowRegisterEntity != null);
        }
        //获取表单定义
        ActFlowFormEntity actFlowFormEntity = actFlowFormMapper.selectById(deploymentId);
        //获取展示数据
        HistoricVariableInstance historicFormDataVariableInstance = historyService.createHistoricVariableInstanceQuery().processInstanceId(processInstanceId).variableName(CommonConstant.FORM_DATA).singleResult();
        Map<String, Object> processVariables = (Map<String, Object>) historicFormDataVariableInstance.getValue();
        //获取操作权限
        actFlowDetail.setActionSetting(actionSetting);

        if (actFlowFormEntity != null){
            JSONObject formJson = JSONObject.parseObject(actFlowFormEntity.getJsonData());
            //权限过滤
            formAndDataPermissionFilter(processVariables,formContentSetting);

            actFlowDetail.setFormPermissionSettings(formContentSetting);
            actFlowDetail.setFormData(processVariables);

            //删除待定-处理票务类型
            //processTicketFormDefinitionByTicketData(formJson,processVariables);

            actFlowDetail.setForm(formJson.toJavaObject(Map.class));
        }else{
            //iframe模式
            HistoricVariableInstance historicVariableInstance = historyService.createHistoricVariableInstanceQuery().processInstanceId(processInstanceId).variableName(CommonConstant.IFRAME_URL).singleResult();
            String iframeUrl = (String) historicVariableInstance.getValue();
            actFlowDetail.setIframeUrl(iframeUrl);
        }

        //审批历史
        List<ActFlowHistoryNode> historyApproveNodeList = getActFlowHistoryNodes(processInstanceId,deploymentId,actFlowDetail,processVariables);
        actFlowDetail.setHistoryNode(historyApproveNodeList);
        return actFlowDetail;
    }
    private ActFlowDetail buildActFlowDetail(String processInstanceId,String deploymentId,List<ActFlowFormContentSetting> formContentSetting, List<ActFlowActionSetting> actionSetting){
        return buildActFlowDetail(processInstanceId,deploymentId,formContentSetting,actionSetting,true);
    }

    private void processTicketFormDefinitionByTicketData(JSONObject formJson,Map<String,Object> formData){
        if (CollUtil.isNotEmpty(formData)){
            Set<String> numberList = new TreeSet<>();
            String numberStr = null;
            for (String key : formData.keySet()) {
                if (key.startsWith("staffName") && !"".equals(numberStr = key.replace("staffName",""))){
                    numberList.add(numberStr);
                }
            }
            JSONArray list = formJson.getJSONArray("list");
            for (Object json : list) {
                JSONObject jsonObject = (JSONObject) json;
                if ("ticket".equals(jsonObject.getString("type"))) {
                    jsonObject.put("needAdd",false);
                    JSONArray options = jsonObject.getJSONArray("list");
                    for (Object option : options) {
                        JSONObject optionJsonObject = (JSONObject) option;
                        optionJsonObject.getJSONObject("options").put("disabled",true);
                    }
                    JSONArray cloneOptions = (JSONArray) options.clone();
                    //清楚第一个
                    cloneOptions.remove(0);
                    for (String number : numberList) {
                        JSONArray newOptions =  (JSONArray)cloneOptions.clone();
                        for (Object cloneOption : newOptions) {
                            JSONObject cloneJsonObject = (JSONObject) cloneOption;
                            cloneJsonObject.put("model",cloneJsonObject.getString("model")+number);
                            cloneJsonObject.put("key",cloneJsonObject.getString("key")+number);
                        }
                        options.addAll(newOptions);
                    }
                }
            }

        }
    }

    private void formAndDataPermissionFilter(Map<String, Object> processVariables,List<ActFlowFormContentSetting> formContentSetting){
        Map<String, String> formContentKeyAndConfig = formContentSetting.stream().collect(Collectors.toMap(ActFlowFormContentSetting::getFormContentKey, ActFlowFormContentSetting::getSetting, (k1, k2) -> k2));

        for (Map.Entry<String, String> keyAndConfig : formContentKeyAndConfig.entrySet()) {
            if (FlowFormContentSettingConstant.HIDE.equals(keyAndConfig.getValue())){
                processVariables.remove(keyAndConfig.getKey());
            }
        }
    }

    private Map<String, String> queryUsernameAndNickname(Set<String> usernames){
        List<ActUser> actUsers = actUserService.queryUserByUsernames(usernames);
        if (CollUtil.isNotEmpty(actUsers)){
            Map<String, String> usernameAndNickname = actUsers.stream().collect(Collectors.toMap(ActUser::getUsername, ActUser::getNickname, (k1, k2) -> k2));
            return usernameAndNickname;
        }
        return new HashMap<>();
    }


    /**
     * 查询审批历史
     * */
    private List<ActFlowHistoryNode> getActFlowHistoryNodes(String processInstanceId,String deploymentId,ActFlowDetail actFlowDetail,Map<String, Object> processVariables) {
        List<HistoricActivityInstance> historicList = historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).orderByHistoricActivityInstanceStartTime().asc().orderByHistoricActivityInstanceEndTime().asc().list();
        historicList = historicList.stream().filter(item-> !(exclusiveGateway.equals(item.getActivityType()) || item.getActivityId().equals(CommonConstant.URGING_SERVICE_NODE_ID) || item.getActivityId().startsWith(FlowNodeTypeConstant.URGING_NODE))).collect(Collectors.toList());
        Set<String> taskIds = new HashSet<>();
        Set<String> users = new HashSet<>();
        //去除开始节点
        historicList.remove(0);
        int size = historicList.size();
        boolean isFinish = false;
        actFlowDetail.setStatus(ActFlowStatusConstant.APPROVE);
        //去除结束节点
        if (size > 0){
            int endIndex = size - 1;
            HistoricActivityInstance endInstance = historicList.get(endIndex);
            if ("end".equals(endInstance.getActivityId())) {
                historicList.remove(endIndex);
                isFinish = true;
                if (actFlowDetail != null){
                    actFlowDetail.setStatus(ActFlowStatusConstant.PASS);
                }
            }else{
                for (HistoricActivityInstance historicActivityInstance : historicList) {
                    if (ActFlowActionSettingConstant.REJECT.equals(historicActivityInstance.getDeleteReason())) {
                        isFinish = true;
                        if (actFlowDetail != null){
                            actFlowDetail.setStatus(ActFlowStatusConstant.REFUSE);
                        }
                        break;
                    }else if (ActFlowStatusConstant.WITHDRAWN.equals(historicActivityInstance.getDeleteReason())) {
                        isFinish = true;
                        if (actFlowDetail != null){
                            actFlowDetail.setStatus(ActFlowStatusConstant.WITHDRAWN);
                        }
                        return new ArrayList<>();
                    }
                }

            }

        }
        if (historicList.isEmpty()){
            return new ArrayList<>();
        }
        for (HistoricActivityInstance historicActivityInstance : historicList) {
            taskIds.add(historicActivityInstance.getTaskId());
            if(historicActivityInstance.getAssignee() != null){
                users.add(historicActivityInstance.getAssignee());
            }
        }

        //获取意见
        Map<String, String> actFlowTaskIdAndCommentMap = new HashMap<>();
        List<ActFlowTaskIdAndCommentEntity> actFlowTaskIdAndCommentList = actExtensionMapper.queryFlowCommentsByTaskIds(taskIds,null,"comment");
        if(CollUtil.isNotEmpty(actFlowTaskIdAndCommentList)){
            actFlowTaskIdAndCommentMap.putAll(actFlowTaskIdAndCommentList.stream().collect(Collectors.toMap(ActFlowTaskIdAndCommentEntity::getTaskId, ActFlowTaskIdAndCommentEntity::getComment , (k1, k2) -> k2)));
        }
        //获取签名
        Set<String> existSignatureTaskIds = actExtensionMapper.queryFlowSignatureByTaskIdsResultExistTaskIds(taskIds);

        //获取转交
        boolean isHaveDelegate = false;
        List<ActFlowDelegateTaskEntity> actDelegateTaskList = actFlowDelegateTaskMapper.selectList(new LambdaQueryWrapper<ActFlowDelegateTaskEntity>().in(ActFlowDelegateTaskEntity::getTaskId, taskIds).orderByAsc(ActFlowDelegateTaskEntity::getTaskId).orderByAsc(ActFlowDelegateTaskEntity::getCreateTime));
        Map<String, List<ActDelegateTaskDetail>> taskIdAndDelegate = new HashMap<>();
        if (CollUtil.isNotEmpty(actDelegateTaskList)){
            for (ActFlowDelegateTaskEntity actFlowDelegateTaskEntity : actDelegateTaskList) {
                users.add(actFlowDelegateTaskEntity.getCurrentUsername());
                users.add(actFlowDelegateTaskEntity.getTargetUsername());
            }
            isHaveDelegate = true;
        }

        // 获取审批人名称
        List<ActUser> actUsers = actUserService.queryUserByUsernames(users);
        Map<String, String> usernameAndNickname = actUsers.stream().collect(Collectors.toMap(ActUser::getUsername, ActUser::getNickname, (k1, k2) -> k2));
        if (isHaveDelegate){
            taskIdAndDelegate.putAll(actDelegateTaskList.stream().collect(Collectors.groupingBy(ActFlowDelegateTaskEntity::getTaskId,Collectors.mapping(item-> new ActDelegateTaskDetail(usernameAndNickname.get(item.getCurrentUsername()),usernameAndNickname.get(item.getTargetUsername()),item.getCreateTime()),Collectors.toList()))));
        }

        //分组取数据
        Map<ActFlowHistoryNode, List<ActFlowHistoryApprover>> historyApproveNodeMap = historicList.stream().collect(Collectors.groupingBy(item -> new ActFlowHistoryNode(item.getActivityName(), item.getActivityId(), null,true), LinkedHashMap::new, Collectors.mapping(item -> {
            ActFlowHistoryApprover actFlowHistoryApprover = new ActFlowHistoryApprover();
            actFlowHistoryApprover.setTaskId(item.getTaskId());
            actFlowHistoryApprover.setUsername(item.getAssignee());
            actFlowHistoryApprover.setNickname(usernameAndNickname.get(item.getAssignee()));
            Date endTime = item.getEndTime();
            //判断是否有转交
            if (!taskIdAndDelegate.isEmpty()){
                actFlowHistoryApprover.setTransferPersonList(taskIdAndDelegate.get(item.getTaskId()));
                if (actFlowHistoryApprover.getTransferPersonList() != null) {
                    actFlowHistoryApprover.setTransfer(true);
                }
            }
            if (endTime != null) {
                //判断是否有意见
                String comment = null;
                if (actFlowTaskIdAndCommentMap.isEmpty() || (comment = actFlowTaskIdAndCommentMap.get(item.getTaskId())) == null) {
                       //没有意见就代表没有审批
                        return actFlowHistoryApprover;
                }
                actFlowHistoryApprover.setEndTime(item.getEndTime());
                actFlowHistoryApprover.setComment(comment.trim());
                actFlowHistoryApprover.setApproverStatus(ActFlowActionSettingConstant.REJECT.equals(item.getDeleteReason()) ? ActFlowActionSettingConstant.REJECT:ActFlowActionSettingConstant.AGREE);
                //判断是否有签名
                if (CollUtil.isNotEmpty(existSignatureTaskIds) && existSignatureTaskIds.contains(item.getTaskId())) {
                    actFlowHistoryApprover.setSignature(true);
                }

            }
            return actFlowHistoryApprover;
        }, Collectors.toList())));

        Map<String,ActFlowHistoryNode> nodeIdAndHistoryApproveNodeMap = new HashMap<>();
        int lastNodeIndex = historyApproveNodeMap.size();
        String oneNodeKey = null;
        int count = 0;
        for (Map.Entry<ActFlowHistoryNode, List<ActFlowHistoryApprover>> item : historyApproveNodeMap.entrySet()) {
            count++;
            ActFlowHistoryNode node = item.getKey();
            if (count == 1){
                oneNodeKey = node.getNodeKey();
            }
            List<ActFlowHistoryApprover> value = item.getValue();
            if (value.get(0).getTaskId() != null) {
                //把未审批的人放到最下面
                if (count == lastNodeIndex && !isFinish){
                    CollUtil.reverse(value);
                    node.setEndNode(false);
                }
                node.setApprovers(value);
            }
            nodeIdAndHistoryApproveNodeMap.put(node.getNodeKey(),node);
        }
        ActFlowConfiguration actFlowConfiguration = actFlowPublishConfigurationMapper.selectById(deploymentId).toActFlowConfiguration();
        actFlowDetail.setFlowName(actFlowConfiguration.getFlowName());
        if (CollUtil.isNotEmpty(actFlowConfiguration.getMultiNodes())){
            List<ActFlowMultiNode> multiNodes = actFlowConfiguration.getMultiNodes();
            List<ActFlowNode> nodes = null;
            for (ActFlowMultiNode multiNode : multiNodes) {
                if (oneNodeKey.equals(multiNode.getNodes().get(0).getId())){
                    nodes = multiNode.getNodes();
                    break;
                }
            }
            List<ActFlowNode> executionStreamNodes = getExecutionStreamNodes(nodes, processVariables);
            return getActFlowHistoryNodeListByNodes(executionStreamNodes, nodeIdAndHistoryApproveNodeMap,processInstanceId,isFinish);
        }else{
            List<ActFlowNode> executionStreamNodes = getExecutionStreamNodes(actFlowConfiguration.getNodes(), processVariables);
            return getActFlowHistoryNodeListByNodes(executionStreamNodes, nodeIdAndHistoryApproveNodeMap,processInstanceId,isFinish);

        }
    }

    private List<ActFlowHistoryNode> getActFlowHistoryNodeListByNodes(List<ActFlowNode> nodes,Map<String,ActFlowHistoryNode> nodeIdAndHistoryApproveNodeMap,String processInstanceId,boolean isFinish){
        //抄送人处理
        List<ActFlowNode> peopleWhoCopiedNodes = nodes.stream().filter(item -> FlowNodeTypeConstant.PEOPLE_WHO_COPIED.equals(item.getNodeType())).collect(Collectors.toList());
        Map<String, List<ActFlowHistoryApprover>> nodeIdAndPeopleWhoCopiedMap = null ;
        if (CollUtil.isNotEmpty(peopleWhoCopiedNodes)){
            List<ActFlowPeopleWhoCopiedEntity> actFlowPeopleWhoCopiedEntities = actFlowPeopleWhoCopiedMapper.selectList(new LambdaQueryWrapper<ActFlowPeopleWhoCopiedEntity>().select(ActFlowPeopleWhoCopiedEntity::getNodeId, ActFlowPeopleWhoCopiedEntity::getPwcUserName,ActFlowPeopleWhoCopiedEntity::getCreateTime,ActFlowPeopleWhoCopiedEntity::getTaskId).eq(ActFlowPeopleWhoCopiedEntity::getProcessInstanceId, processInstanceId));
            if (CollUtil.isNotEmpty(actFlowPeopleWhoCopiedEntities)){
                Set<String> usernames = actFlowPeopleWhoCopiedEntities.stream().map(ActFlowPeopleWhoCopiedEntity::getPwcUserName).collect(Collectors.toSet());
                Map<String, String> usernameAndNickname = queryUsernameAndNickname(usernames);
                nodeIdAndPeopleWhoCopiedMap = actFlowPeopleWhoCopiedEntities.stream().collect(Collectors.groupingBy(ActFlowPeopleWhoCopiedEntity::getNodeId, Collectors.mapping(item->{
                    ActFlowHistoryApprover actFlowHistoryApprover = new ActFlowHistoryApprover();
                    actFlowHistoryApprover.setTaskId(item.getTaskId());
                    String nickname = usernameAndNickname.get(item.getPwcUserName());
                    actFlowHistoryApprover.setNickname(nickname == null ? item.getPwcUserName():nickname);
                    actFlowHistoryApprover.setEndTime(item.getCreateTime());
                    actFlowHistoryApprover.setApproverStatus(ActFlowActionSettingConstant.AGREE);
                    return actFlowHistoryApprover;
                }, Collectors.toList())));
            }
        }
        List<ActFlowHistoryNode> data = new ArrayList<>();
        boolean endNode = isFinish;
        for (ActFlowNode node : nodes) {
            ActFlowHistoryNode actFlowHistoryNode = nodeIdAndHistoryApproveNodeMap.get(node.getId());
            if (actFlowHistoryNode != null){
                if (FlowNodeTypeConstant.MESSAGE_NODE.equals(node.getNodeType()) && CollUtil.isNotEmpty(actFlowHistoryNode.getApprovers())) {
                    ActFlowHistoryApprover actFlowHistoryApprover = actFlowHistoryNode.getApprovers().get(0);
                    actFlowHistoryApprover.setUsername(null);
                }
                if (FlowNodeTypeConstant.PEOPLE_WHO_COPIED.equals(node.getNodeType()) && nodeIdAndPeopleWhoCopiedMap != null){
                    actFlowHistoryNode.setApprovers(nodeIdAndPeopleWhoCopiedMap.get(node.getId()));
                }
                if (!isFinish){
                    endNode = actFlowHistoryNode.isEndNode();
                }
                data.add(actFlowHistoryNode);
                continue;
            }
            if (FlowNodeTypeConstant.PEOPLE_WHO_COPIED.equals(node.getNodeType()) && nodeIdAndPeopleWhoCopiedMap != null){
                actFlowHistoryNode = new ActFlowHistoryNode(node.getNodeName(), node.getId(), nodeIdAndPeopleWhoCopiedMap.get(node.getId()), endNode);
                data.add(actFlowHistoryNode);
                continue;
            }
            data.add(new ActFlowHistoryNode(node.getNodeName(),node.getId(),null,endNode));
        }
        return data;
    }

    @Override
    public Page<ActFlowDone> queryDoneList(QueryActFlowDone queryActFlowDone, Page page) {
        ActUserDetail currentLoginUser = actBasicService.getCurrentLoginUser();
        String currentTenantId = actBasicService.getCurrentTenantId();

        if (StrUtil.isNotBlank(queryActFlowDone.getProcessName())){
            queryActFlowDone.setProcessName("%"+queryActFlowDone.getProcessName()+"%");
        }
        Page<ActFlowDone> resultPage = actExtensionMapper.queryDoneList(page,currentLoginUser.getUsername(), queryActFlowDone,currentTenantId);
        List<ActFlowDone> actFlowDoneList = resultPage.getRecords();
        if (CollUtil.isEmpty(actFlowDoneList)){
            return resultPage;
        }

        resultPage.setRecords(actFlowDoneList);

        Set<String> deploymentIds = actFlowDoneList.stream().map(ActFlowDone::getDeploymentId).collect(Collectors.toSet());
        Map<String, ActFlowPublishConfigEntity> deploymentIdAndPublishMap = queryDeploymentIdAndPublishMap(deploymentIds);
        Set<String> usernames = actFlowDoneList.stream().map(ActFlowDone::getApplyer).collect(Collectors.toSet());
        Set<String> processInstanceIds = actFlowDoneList.stream().map(ActFlowDone::getProcessInstanceId).collect(Collectors.toSet());
        List<ActFlowProIdAndNode> proIdAndNodeList = queryFlowProIdAndNodeGetGroupMax(processInstanceIds, null,false);
        Map<String, List<ActFlowProIdAndNode>> proInsIdAndNodeList = null;
        if (CollUtil.isNotEmpty(proIdAndNodeList)){
            usernames.addAll(proIdAndNodeList.stream().filter(item -> item.getAssignee() != null).map(ActFlowProIdAndNode::getAssignee).collect(Collectors.toSet()));
        }
        Map<String, String> usernameAndNickname = queryUsernameAndNickname(usernames);
        if (CollUtil.isNotEmpty(proIdAndNodeList)){
            proInsIdAndNodeList = proIdAndNodeList.stream().collect(Collectors.groupingBy(ActFlowProIdAndNode::getProcessInstanceId, Collectors.mapping(item->{
                if (!usernameAndNickname.isEmpty() && item.getAssignee() != null){
                    item.setAssignee(usernameAndNickname.get(item.getAssignee()));
                }
                return item;
            }, Collectors.toList())));
        }

        Map<String, Map<String, Object>> processInstanceIdAndFormData = null;
        Map<String, List<ActFlowFormContentSetting>> formDataPermissionMap = new HashMap<>();
        //是否需要表单数据
        processInstanceIdAndFormData = queryVariableByExecutionId(processInstanceIds);
        List<ActFlowNodeEntity> actFlowNodeEntities = actFlowNodeMapper.selectBatchIds(actFlowDoneList.stream().map(ActFlowDone::getNodeId).collect(Collectors.toSet()));
        if (CollUtil.isNotEmpty(actFlowNodeEntities)){
            formDataPermissionMap.putAll(actFlowNodeEntities.stream().collect(Collectors.toMap(ActFlowNodeEntity::getId, item-> item.transitionActFlowNode().getConfigurationItem().getFormContentSetting(), (v1, v2) -> v2)));
        }

        for (ActFlowDone actFlowDone : actFlowDoneList) {
            if (ActFlowActionSettingConstant.REJECT.equals(actFlowDone.getApprovalOperation())) {
                actFlowDone.setApprovalOperation("已拒绝");
                actFlowDone.setStatus(ActFlowStatusConstant.REFUSE);
            }else if (ActFlowStatusConstant.WITHDRAWN.equals(actFlowDone.getApprovalOperation())){
                actFlowDone.setApprovalOperation("已撤回");
                actFlowDone.setStatus(ActFlowStatusConstant.WITHDRAWN);
            }else{
                actFlowDone.setApprovalOperation("已通过");
            }
            actFlowDone.setApplyer(usernameAndNickname.get(actFlowDone.getApplyer()));
            ActFlowPublishConfigEntity publishConfig = deploymentIdAndPublishMap.get(actFlowDone.getDeploymentId());
            if (publishConfig != null){
                actFlowDone.setIconType(publishConfig.getIconType());
            }
            //如果是已拒绝就没有必要查询审批人数据了
            if (proInsIdAndNodeList != null && actFlowDone.getStatus() == null){
                List<ActFlowProIdAndNode> actFlowProIdAndNodes = proInsIdAndNodeList.get(actFlowDone.getProcessInstanceId());
                if (CollUtil.isNotEmpty(actFlowProIdAndNodes)){
                    ActFlowProIdAndNode actFlowProIdAndNode = actFlowProIdAndNodes.get(0);
                    if (ActFlowActionSettingConstant.REJECT.equals(actFlowProIdAndNode.getDeleteReason())){
                        actFlowDone.setStatus(ActFlowStatusConstant.REFUSE);
                    }else if (ActFlowStatusConstant.WITHDRAWN.equals(actFlowProIdAndNode.getDeleteReason())) {
                        actFlowDone.setStatus(ActFlowStatusConstant.WITHDRAWN);
                    }else if ("endEvent".equals(actFlowProIdAndNode.getActType())) {
                        actFlowDone.setStatus(ActFlowStatusConstant.PASS);
                    }else{
                        actFlowDone.setStatus(ActFlowStatusConstant.APPROVE);
                        actFlowDone.setCurrentApprovalUserList(actFlowProIdAndNodes.stream().filter(item -> "userTask".equals(item.getActType()) && item.getEndTime() == null).map(ActFlowProIdAndNode::getAssignee).collect(Collectors.toList()));
                    }
                }
            }
            //设置表单数据
            if (processInstanceIdAndFormData != null){
                Map<String, Object> formData = processInstanceIdAndFormData.get(actFlowDone.getProcessInstanceId());
                //权限处理
                FormDataPermissionUtils.processFormDataPermission(formData,formDataPermissionMap.get(actFlowDone.getNodeId()));
                if (queryActFlowDone.isNeedFormData()){
                    actFlowDone.setFormData(formData);
                }

                if (publishConfig != null){
                    actFlowDone.setSummary(ELUtils.getSummary(publishConfig.getSummary(),publishConfig.getManyConditionJson(),formData));
                }
            }
        }
        return resultPage;
    }


    private List<ActFlowProIdAndNode> queryFlowProIdAndNodeGetGroupMax(Set<String> processInstanceIds,String type,boolean unapproved){
        List<ActFlowProIdAndNode> proIdAndNodeList = actExtensionMapper.queryFlowProIdAndNodeByInstanceIds(processInstanceIds, type,unapproved);
        if (CollUtil.isEmpty(proIdAndNodeList)){
            return null;
        }
        proIdAndNodeList = proIdAndNodeList.stream().filter(item-> !(item.getActId().startsWith(FlowNodeTypeConstant.URGING_NODE) || item.getActId().equals(CommonConstant.URGING_SERVICE_NODE_ID))).collect(Collectors.toList());
        return queryFlowProIdAndNodeGetGroupMax(proIdAndNodeList);
    }


    private List<ActFlowProIdAndNode> queryFlowProIdAndNodeGetGroupMax(List<ActFlowProIdAndNode> proIdAndNodeList){
            List<ActFlowProIdAndNode> dataList = new ArrayList<>();
            String lastProcessInstanceId = null;
            String lastActId = null;
            for (ActFlowProIdAndNode actFlowProIdAndNode : proIdAndNodeList) {
                if (lastProcessInstanceId == null){
                    lastProcessInstanceId = actFlowProIdAndNode.getProcessInstanceId();
                    lastActId = actFlowProIdAndNode.getActId();
                }
                if (lastProcessInstanceId.equals(actFlowProIdAndNode.getProcessInstanceId())){
                    if (lastActId.equals(actFlowProIdAndNode.getActId())){
                        dataList.add(actFlowProIdAndNode);
                    }
                }else{
                    lastProcessInstanceId = actFlowProIdAndNode.getProcessInstanceId();
                    lastActId = actFlowProIdAndNode.getActId();
                    dataList.add(actFlowProIdAndNode);
                }
            }
            return dataList;
    }

    @Override
    public Page<ActFlowMyApply> queryMyApplyList(QueryActFlowMyApply queryActFlowMyApply, Page page) {
        if (ActFlowStatusConstant.REFUSE.equals(queryActFlowMyApply.getProcessStatus())){
            queryActFlowMyApply.setProcessStatus(ActFlowActionSettingConstant.REJECT);
        }
        ActUserDetail currentLoginUser = actBasicService.getCurrentLoginUser();
        String currentTenantId = actBasicService.getCurrentTenantId();

        page.setSearchCount(false);
        Page<ActFlowMyApply> resultPage = actExtensionMapper.queryMyApplyList(page,currentLoginUser.getUsername(), queryActFlowMyApply,currentTenantId);
        List<ActFlowMyApply> actFlowMyApplies = resultPage.getRecords();
        if (CollUtil.isEmpty(actFlowMyApplies)){
            return resultPage;
        }
        resultPage.setTotal(actExtensionMapper.queryMyApplyCount(currentLoginUser.getUsername(), queryActFlowMyApply,currentTenantId));
        List<String> keys = actFlowMyApplies.stream().map(ActFlowMyApply::getProcessKey).collect(Collectors.toList());
        Set<String> patternUrlKeys = null;
        if (CollUtil.isNotEmpty(keys)){
            List<ActFlowConfigurationEntity> actFlowConfigurationEntities = actFlowConfigurationMapper.selectList(new LambdaQueryWrapper<ActFlowConfigurationEntity>().select(ActFlowConfigurationEntity::getFlowKey).in(ActFlowConfigurationEntity::getFlowKey, keys).eq(ActFlowConfigurationEntity::getPattern, ApprovalConfigConstant.PATTERN_URL));
            patternUrlKeys = actFlowConfigurationEntities.stream().map(ActFlowConfigurationEntity::getFlowKey).collect(Collectors.toSet());
        }

        Set<String> deploymentIds = actFlowMyApplies.stream().map(ActFlowMyApply::getDeploymentId).collect(Collectors.toSet());
        Map<String, ActFlowPublishConfigEntity> deploymentIdAndPublishMap = queryDeploymentIdAndPublishMap(deploymentIds);
        Set<String> instanceIds = actFlowMyApplies.stream().map(ActFlowMyApply::getProcessInstanceId).collect(Collectors.toSet());

        GenericReferenceEntity<List<ActFlowProIdAndNode>, Map<String, Boolean>> listMapGenericReferenceEntity = BasicCommonUtils.queryFlowProIdAndNodeGetGroupMaxAndWithdraw(actExtensionMapper.queryFlowProIdAndNodeByInstanceIds(instanceIds, null,false));
        List<ActFlowProIdAndNode> proIdAndNodeList = listMapGenericReferenceEntity.getOneData();
        Map<String, Boolean> processInstanceIdAndWithdraw = listMapGenericReferenceEntity.getTwoData();
        Map<String, List<ActFlowProIdAndNode>> proInsIdAndNodeList = null;
        Map<String, Boolean> nodeIdAndUrging = null;
        //当前审批人
        if (CollUtil.isNotEmpty(proIdAndNodeList)){
            Set<String> usernames = proIdAndNodeList.stream().filter(item->item.getAssignee() != null).map(ActFlowProIdAndNode::getAssignee).collect(Collectors.toSet());
            Map<String, String> usernameAndNickname = queryUsernameAndNickname(usernames);
            Set<String> actIdSet = new HashSet<>();
            proInsIdAndNodeList = proIdAndNodeList.stream().collect(Collectors.groupingBy(ActFlowProIdAndNode::getProcessInstanceId, Collectors.mapping(item->{
                if (!usernameAndNickname.isEmpty()){
                    item.setAssignee(usernameAndNickname.get(item.getAssignee()));
                }
                if (!actIdSet.contains(item.getActId())){
                    actIdSet.add(item.getActId());
                }
                return item;
            }, Collectors.toList())));

            List<ActFlowNodeEntity> actFlowNodeEntities = actFlowNodeMapper.selectBatchIds(actIdSet);
            if (CollUtil.isNotEmpty(actFlowNodeEntities)){
                nodeIdAndUrging = actFlowNodeEntities.stream().collect(Collectors.toMap(item -> item.getId(), item -> item.transitionActFlowNode().getConfigurationItem().getFlowUrgingConfiguration() != null));

            }
        }

        Map<String, Map<String, Object>> processInstanceIdAndFormData = null;
        Map<String, List<ActFlowFormContentSetting>> formDataPermissionMap = new HashMap<>();

        List<ActFlowNodeEntity> actFlowNodeEntities = actFlowNodeMapper.selectBatchIds(deploymentIds);
        if (CollUtil.isNotEmpty(actFlowNodeEntities)){
            formDataPermissionMap.putAll(actFlowNodeEntities.stream().collect(Collectors.toMap(ActFlowNodeEntity::getId, ActFlowNodeEntity::transitionActFlowFormContentSettingList, (v1, v2) -> v2)));
        }
        processInstanceIdAndFormData = queryVariableByExecutionId(instanceIds);


        Set<String> flowKeyList = actFlowMyApplies.stream().map(ActFlowMyApply::getProcessKey).collect(Collectors.toSet());
        Map<String, Boolean> flowKeyAndReapply = actFlowPermissionMapper.findCountByFlowKeys(flowKeyList).stream().collect(Collectors.toMap(item -> item.getFlowKey(), item -> item.getFindCount() > 0));
        for (ActFlowMyApply apply : actFlowMyApplies) {
            Date endTime = apply.getEndTime();
            if (proInsIdAndNodeList != null){
                List<ActFlowProIdAndNode> actFlowProIdAndNodes = proInsIdAndNodeList.get(apply.getProcessInstanceId());
                if (CollUtil.isNotEmpty(actFlowProIdAndNodes)){
                    ActFlowProIdAndNode actFlowProIdAndNode = actFlowProIdAndNodes.get(0);
                    apply.setCurrentApprovalDodeName(actFlowProIdAndNode.getActName());
                    apply.setCurrentApprovalUserList(actFlowProIdAndNodes.stream().filter(item->item.getEndTime() == null).map(ActFlowProIdAndNode::getAssignee).collect(Collectors.toList()));
                    if (nodeIdAndUrging != null){
                        Boolean urging = nodeIdAndUrging.get(actFlowProIdAndNode.getActId());
                        apply.setUrging(urging == null? false:urging);
                    }
                }
            }
            if (endTime != null){
                if (apply.getDeleteReason() == null){
                    apply.setStatus(ActFlowStatusConstant.PASS);
                }else{
                    apply.setStatus(ActFlowStatusConstant.WITHDRAWN.equals(apply.getDeleteReason()) ? ActFlowStatusConstant.WITHDRAWN:ActFlowStatusConstant.REFUSE);
                    //只有驳回和撤回后，才能设置判断是否可以重新提交
                    Boolean reapply = null;
                    if (flowKeyAndReapply != null && (reapply = flowKeyAndReapply.get(apply.getProcessKey()) != null)
                            && (patternUrlKeys == null || !patternUrlKeys.contains(apply.getProcessKey()))){
                        apply.setReapply(reapply);
                    }
                }
            }else{
                apply.setStatus(ActFlowStatusConstant.APPROVE);

                Boolean withdraw = processInstanceIdAndWithdraw.get(apply.getProcessInstanceId());
                if (null != withdraw){
                    apply.setWithdraw(withdraw);
                }else{
                    apply.setWithdraw(true);
                }
            }
            ActFlowPublishConfigEntity publishConfig = deploymentIdAndPublishMap.get(apply.getDeploymentId());
            if (publishConfig != null){
                apply.setIconType(publishConfig.getIconType());
            }

            if (processInstanceIdAndFormData != null){
                Map<String, Object> formData = processInstanceIdAndFormData.get(apply.getProcessInstanceId());
                //权限处理
                FormDataPermissionUtils.processFormDataPermission(formData,formDataPermissionMap.get(apply.getDeploymentId()));
                if (queryActFlowMyApply.isNeedFormData()){
                    apply.setFormData(formData);
                }
                if (publishConfig != null){
                    apply.setSummary(ELUtils.getSummary(publishConfig.getSummary(),publishConfig.getManyConditionJson(),formData));
                }
            }


            apply.setEndTime(null);
            apply.setDeleteReason(null);
            apply.setDeploymentId(null);
        }
        return resultPage;
    }

    @Override
    public ActFlowPermission queryFlowPermission(String flowId) {
        List<ActFlowPermissionEntity> actFlowPermissionList = actFlowPermissionMapper.selectList(new LambdaQueryWrapper<ActFlowPermissionEntity>().eq(ActFlowPermissionEntity::getFlowId, flowId));
        ActFlowPermission actFlowPermission = new ActFlowPermission();
        actFlowPermission.setFlowId(flowId);
        if (CollUtil.isNotEmpty(actFlowPermissionList)){
            Map<String, List<ActFlowPermissionEntity>> typeAndEntityMap = actFlowPermissionList.stream().collect(Collectors.groupingBy(ActFlowPermissionEntity::getPermissionType));
            List<ActFlowPermissionEntity> deptPermission = typeAndEntityMap.get(ActFlowPermissionConstant.DEPT);

            if (CollUtil.isNotEmpty(deptPermission)){
                Set<String> deptCodes = deptPermission.stream().map(ActFlowPermissionEntity::getPermissionValue).collect(Collectors.toSet());
                actFlowPermission.setDeptList(actDeptService.queryDeptByDeptCodes(deptCodes));
            }

            List<ActFlowPermissionEntity> userPermission = typeAndEntityMap.get(ActFlowPermissionConstant.USER);
            if (CollUtil.isNotEmpty(userPermission)){
                Set<String> usernames = userPermission.stream().map(ActFlowPermissionEntity::getPermissionValue).collect(Collectors.toSet());
                ActUser allUser = null;
                if (usernames.remove("all")) {
                    allUser = new ActUser();
                    allUser.setNickname("所有成员");
                    allUser.setUsername("all");
                }
                List<ActUser> users = new ArrayList<>();
                if (CollUtil.isNotEmpty(usernames)){
                    users.addAll(actUserService.queryUserByUsernames(usernames));
                }
                if (allUser != null){
                    users.add(allUser);
                }
                actFlowPermission.setUserlist(users);
            }

            List<ActFlowPermissionEntity> rolePermission = typeAndEntityMap.get(ActFlowPermissionConstant.ROLE);
            if (CollUtil.isNotEmpty(rolePermission)){
                Set<String> roleCodes = rolePermission.stream().map(ActFlowPermissionEntity::getPermissionValue).collect(Collectors.toSet());
                actFlowPermission.setRoleList(actRoleService.queryRoleByRoleCodes(roleCodes));
            }

        }
        return actFlowPermission;
    }

    @Override
    public ActFlowConfiguration queryFlowConfiguration(String flowId) {
        ActFlowConfigurationEntity entity = actFlowConfigurationMapper.selectById(flowId);
        ActFlowConfiguration actFlowConfiguration = entity.toActFlowConfiguration();
        if (CollUtil.isNotEmpty(actFlowConfiguration.allFlowNode())){
            List<ActFlowNode> actFlowNodes = actFlowConfiguration.allFlowNode().stream().filter(item -> FlowNodeTypeConstant.MESSAGE_NODE.equals(item.getNodeType())).collect(Collectors.toList());
            if (!actFlowNodes.isEmpty()){
                Set<String> messageKeySet = actFlowNodes.stream().map(ActFlowNode::getMessageKey).collect(Collectors.toSet());
                List<ActFlowNodeKeyEntity> flowNodeKeyList = null ;
                if (CollUtil.isNotEmpty(messageKeySet) && CollUtil.isNotEmpty(flowNodeKeyList = actFlowNodeKeyMapper.selectList(new LambdaQueryWrapper<ActFlowNodeKeyEntity>().in(ActFlowNodeKeyEntity::getNodeKey, messageKeySet)))){
                    Map<String, String> messageKeyAndDescription = flowNodeKeyList.stream().collect(Collectors.toMap(ActFlowNodeKeyEntity::getNodeKey, ActFlowNodeKeyEntity::getDescription, (v1, v2) -> v2));
                    for (ActFlowNode actFlowNode : actFlowNodes) {
                        actFlowNode.setMessageName(messageKeyAndDescription.get(actFlowNode.getMessageKey()));
                    }
                }
            }
        }
        actFlowConfiguration.setId(entity.getId());
        actFlowConfiguration.setPublish(entity.getPublish());
        return actFlowConfiguration;
    }

    @Override
    public ActFlowConfiguration queryFlowConfigurationByFlowKey(String flowKey) {
        ActFlowConfigurationEntity entity = actFlowConfigurationMapper.selectOne(new LambdaQueryWrapper<ActFlowConfigurationEntity>().eq(ActFlowConfigurationEntity::getFlowKey,flowKey));
        ActFlowConfiguration actFlowConfiguration = entity.toActFlowConfiguration();
        actFlowConfiguration.setId(entity.getId());
        actFlowConfiguration.setPublish(entity.getPublish());
        return actFlowConfiguration;
    }

    @Override
    public ActFlowApply queryFlowApply(String flowKey) {
        Deployment deployment = repositoryService.createDeploymentQuery().deploymentKey(flowKey).latest().singleResult();
        ActFlowPublishConfigEntity flowEntity = actFlowPublishConfigurationMapper.selectById(deployment.getId());
        ActFlowConfiguration actFlowConfiguration = flowEntity.toActFlowConfiguration();
        ActFlowApply actFlowApply = buildActFlowApply(actFlowConfiguration);
        actFlowApply.setDeploymentId(deployment.getId());
        return actFlowApply;
    }

    private ActFlowApply buildActFlowApply(ActFlowConfiguration actFlowConfiguration) {
        ActFlowApply actFlowApply = new ActFlowApply();
        //获取发起人配置
        actFlowApply.setFormPermissionSettings(actFlowConfiguration.getInitiatorFormContentSetting());
        //设置表单
        actFlowApply.setForm(JSONObject.parseObject(actFlowConfiguration.getFormJson(),Map.class));

        List<ActFlowCondition> conditions = actFlowConfiguration.allFlowNodeCondition();
        if (CollUtil.isNotEmpty(conditions)) {
            actFlowApply.setAttentionConditionKeys(conditions.stream().map(ActFlowCondition::getFormElementKey).collect(Collectors.toSet()));
        }else if (CollUtil.isNotEmpty(actFlowConfiguration.allFlowNode())){
            actFlowApply.setNodes(actFlowConfiguration.allFlowNode().stream().filter(item-> !FlowNodeTypeConstant.LINK_NODE.equals(item.getNodeType())).collect(Collectors.toList()));
        }
        return actFlowApply;
    }

    @Override
    public ActFlowDetail queryFlowDetailByPwcId(String pwcId) {
        ActFlowPeopleWhoCopiedEntity entity = actFlowPeopleWhoCopiedMapper.selectById(pwcId);
        HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(entity.getProcessInstanceId()).singleResult();
        ActFlowNode actFlowNode = actFlowNodeMapper.selectById(entity.getNodeId()).transitionActFlowNode();
        ActFlowDetail actFlowDetail = buildActFlowDetail(entity.getProcessInstanceId(), historicProcessInstance.getDeploymentId(), actFlowNode.getConfigurationItem().getFormContentSetting(), actFlowNode.getConfigurationItem().getActionSetting());
        actFlowDetail.setStartTime(historicProcessInstance.getStartTime());
        actFlowDetail.setInitiator(queryUsernameAndNickname(CollUtil.newHashSet(historicProcessInstance.getStartUserId())).get(historicProcessInstance.getStartUserId()));
        actFlowDetail.setDeploymentId(historicProcessInstance.getDeploymentId());
        actFlowDetail.setFlowKey(historicProcessInstance.getProcessDefinitionKey());
        return actFlowDetail;
    }

    @Override
    public String queryDigitalSignatureByTaskId(String taskId) {
        List<Comment> taskComments = taskService.getTaskComments(taskId, CommonConstant.SIGNATURE_TYPE);
        if (CollUtil.isNotEmpty(taskComments)){
            return taskComments.get(0).getFullMessage();
        }
        return "";
    }

    @Override
    public List<ActFlowInstance> queryFlowInstanceByKey(String key) {
        List<Task> list = taskService.createTaskQuery().taskAssignee(CommonConstant.MESSAGE_PREFIX_KEY + key).list();
        if (CollUtil.isEmpty(list)){
            return new ArrayList<>();
        }
        Set<String> processDefinitionIds = list.stream().map(Task::getProcessDefinitionId).collect(Collectors.toSet());
        List<ProcessDefinition> processDefinitionList = repositoryService.createProcessDefinitionQuery().processDefinitionIds(processDefinitionIds).list();
        Map<String, ProcessDefinition> instanceIdAndDefinition = processDefinitionList.stream().collect(Collectors.toMap(ProcessDefinition::getId, processDefinition -> processDefinition, (k1, k2) -> k2));
        List<ActFlowInstance> dataList = list.stream().map(task -> {
            ActFlowInstance actFlowInstance = new ActFlowInstance();
            actFlowInstance.setNodeName(task.getName());
            actFlowInstance.setNodeId(task.getTaskDefinitionKey());
            actFlowInstance.setInstanceId(task.getProcessInstanceId());
            ProcessDefinition processDefinition = instanceIdAndDefinition.get(task.getProcessDefinitionId());
            if (processDefinition != null){
                actFlowInstance.setFlowKey(processDefinition.getKey());
                actFlowInstance.setFlowName(processDefinition.getName());
            }
            return actFlowInstance;
        }).collect(Collectors.toList());

        return dataList;
    }

    @Override
    public Page<ActFlowTransferRecord> queryTransferRecordList(QueryActFlowTransferRecord queryActFlowTransferRecord, Page page) {
        String username = actBasicService.getCurrentLoginUser().getUsername();
        Page<ActFlowDelegateTaskEntity> pageData = actFlowDelegateTaskMapper.selectPage(page, new LambdaQueryWrapper<ActFlowDelegateTaskEntity>().eq(ActFlowDelegateTaskEntity::getCurrentUsername,username).orderByDesc(ActFlowDelegateTaskEntity::getCreateTime));
        Page<ActFlowTransferRecord> resultData = new Page<>();
        if (pageData.getTotal() == 0){
            return resultData;
        }
        resultData.setSize(pageData.getSize());
        resultData.setTotal(pageData.getTotal());
        resultData.setCurrent(pageData.getCurrent());
        Set<String> usernames = new HashSet<>();
        for (ActFlowDelegateTaskEntity record : pageData.getRecords()) {
            usernames.add(record.getTargetUsername());
            usernames.add(record.getInitiator());
        }
        Map<String, String> usernameAndNickname = queryUsernameAndNickname(usernames);
        List<ActFlowTransferRecord> listData = pageData.getRecords().stream().map(item -> {
            ActFlowTransferRecord actFlowTransferRecord = new ActFlowTransferRecord();
            actFlowTransferRecord.setTaskId(item.getTaskId());
            actFlowTransferRecord.setCreateTime(item.getCreateTime());
            actFlowTransferRecord.setTargetUser(usernameAndNickname.get(item.getTargetUsername()));
            actFlowTransferRecord.setDescription(usernameAndNickname.get(item.getInitiator())+"发起的"+item.getProcessName());
            return actFlowTransferRecord;
        }).collect(Collectors.toList());
        resultData.setRecords(listData);
        return resultData;
    }

    @Override
    public List<ActFlowNode> queryExecutionStream(String deploymentId, Map<String, Object> formData) {
        ActFlowPublishConfigEntity flowEntity = actFlowPublishConfigurationMapper.selectById(deploymentId);
        ActFlowConfiguration actFlowConfiguration = flowEntity.toActFlowConfiguration();
        return executionStream(actFlowConfiguration,formData);
    }

    private List<ActFlowNode> executionStream(ActFlowConfiguration actFlowConfiguration,Map<String, Object> formData){
        if (CollUtil.isNotEmpty(actFlowConfiguration.getNodes())){
            List<ActFlowNode> executionStreamNodes = getExecutionStreamNodesForErrorResultEmpty(actFlowConfiguration.getNodes(), formData).getOneData();
            processNodeFutilityData(executionStreamNodes);
            return executionStreamNodes;
        }else{
            for (ActFlowMultiNode multiNode : actFlowConfiguration.getMultiNodes()) {
                if (VerifyConditionUtils.verifyConditionGroups(multiNode.employConditionGroups(),formData) && CollUtil.isNotEmpty(multiNode.getNodes())){
                    List<ActFlowNode> executionStreamNodes = getExecutionStreamNodesForErrorResultEmpty(multiNode.getNodes(), formData).getOneData();
                    processNodeFutilityData(executionStreamNodes);
                    return executionStreamNodes;
                }
            }
        }
        return new ArrayList<>();
    }

    @Override
    public ActFlowApply queryFlowApplyByFlowId(String flowId) {
        ActFlowConfiguration actFlowConfiguration = actFlowConfigurationMapper.selectById(flowId).toActFlowConfiguration();
        ActFlowApply actFlowApply = buildActFlowApply(actFlowConfiguration);
        actFlowApply.setFlowId(flowId);
        return actFlowApply;
    }

    @Override
    public List<ActFlowApprovalHistory> queryApprovalHistory(String processInstanceId,boolean isQueryToApprove) {
        if (StrUtil.isBlank(processInstanceId)){
            throw new RequestParamException("参数不能为空");
        }
        List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId).orderByHistoricTaskInstanceStartTime().asc().orderByHistoricTaskInstanceEndTime().desc().list();
        Set<String> taskIds = list.stream().map(HistoricTaskInstance::getId).collect(Collectors.toSet());

        List<ActFlowTaskIdAndCommentEntity> actFlowTaskIdAndCommentList = actExtensionMapper.queryFlowCommentsByTaskIds(taskIds,null,"comment");
        Map<String,String> commentMap = new HashMap<>();
        if (CollUtil.isNotEmpty(actFlowTaskIdAndCommentList)){
            commentMap.putAll(actFlowTaskIdAndCommentList.stream().collect(Collectors.toMap(ActFlowTaskIdAndCommentEntity::getTaskId, ActFlowTaskIdAndCommentEntity::getComment)));
        }
        Stream<HistoricTaskInstance> listStream = list.stream();
        if (isQueryToApprove){
            listStream = listStream.filter(item -> commentMap.containsKey(item.getId()));
        }

        Map<ActFlowApprovalHistory, List<ActFlowApprover>> resultMap = listStream.collect(Collectors.groupingBy(item -> new ActFlowApprovalHistory(item.getTaskDefinitionKey(), item.getName()),LinkedHashMap::new, Collectors.mapping(task -> {
            String comment = commentMap.get(task.getId());
            return new ActFlowApprover(task.getId(), task.getAssignee(), task.getStartTime(), task.getEndTime(), task.getDurationInMillis(),comment,comment != null);
        }, Collectors.toList())));

        List<ActFlowApprovalHistory> resultList = new ArrayList<>();
        for (Map.Entry<ActFlowApprovalHistory, List<ActFlowApprover>> actFlowApprovalHistoryListEntry : resultMap.entrySet()) {
            List<ActFlowApprover> flowApprovers = actFlowApprovalHistoryListEntry.getValue();
            ActFlowApprovalHistory flowApprovalHistory = actFlowApprovalHistoryListEntry.getKey();
            flowApprovalHistory.setApprovers(flowApprovers);
            if (!isQueryToApprove && CollUtil.isNotEmpty(flowApprovers)){
                flowApprovalHistory.setApprovers(flowApprovers.stream().sorted((to1,to2)-> {
                    if (to1.isToApprove() && to2.isToApprove()){
                        return to1.getTaskEndTime().getTime() > to2.getTaskEndTime().getTime() ? -1:1;
                    }
                    return to1.isToApprove() ? -1:1;
                }).collect(Collectors.toList()));
            }
            resultList.add(flowApprovalHistory);
        }
        return resultList;
    }

    @Override
    public List<ActFlowDetail> queryFlowDetailHistory(String processInstanceId) {
        List<ActFlowDetail> resultList = new ArrayList<ActFlowDetail>();
        String queryId = processInstanceId;
        ActFlowRegisterEntity actFlowRegisterEntity;
        while((actFlowRegisterEntity = flowRegisterMapper.selectById(queryId)) != null){
            queryId = actFlowRegisterEntity.getParentId();
            ActFlowDetail actFlowDetail = buildMyApplyFlowDetail(queryId,false);
            resultList.add(actFlowDetail);
        }
        return resultList;
    }

    @Override
    public List<ActFlowNode> queryExecutionStreamByFlowId(String flowId, Map<String, Object> formData) {
        ActFlowConfiguration actFlowConfiguration = actFlowConfigurationMapper.selectById(flowId).toActFlowConfiguration();
        return executionStream(actFlowConfiguration,formData);
    }

    private void processNodeFutilityData(List<ActFlowNode> executionStreamNodes){
        if (CollUtil.isNotEmpty(executionStreamNodes)){
            for (ActFlowNode executionStreamNode : executionStreamNodes) {
                executionStreamNode.setNodeLink(null);
                executionStreamNode.setConfigurationItem(null);
            }
        }
    }

    private List<ActFlowNode> getExecutionStreamNodes(List<ActFlowNode> actFlowNodes,Map<String, Object> formData){
        List<ActFlowNode> executionStreamNodes = new ArrayList<>();
        for (ActFlowNode actFlowNode : actFlowNodes) {
            if (FlowNodeTypeConstant.LINK_NODE.equals(actFlowNode.getNodeType())){
                List<ActFlowMultiNode> nodeLink = actFlowNode.getNodeLink();
                for (ActFlowMultiNode actFlowMultiNode : nodeLink) {
                    if (VerifyConditionUtils.verifyConditionGroups(actFlowMultiNode.employConditionGroups(),formData)) {
                        executionStreamNodes.addAll(getExecutionStreamNodes(actFlowMultiNode.getNodes(),formData));
                    }
                }
            }else{
                executionStreamNodes.add(actFlowNode);
            }
        }
        return executionStreamNodes;
    }

    private GenericReferenceEntity<List<ActFlowNode>,Boolean> getExecutionStreamNodesForErrorResultEmpty(List<ActFlowNode> actFlowNodes,Map<String, Object> formData){
        List<ActFlowNode> executionStreamNodes = new ArrayList<>();
        GenericReferenceEntity<List<ActFlowNode>,Boolean> resultData = new GenericReferenceEntity(executionStreamNodes, false);
        for (ActFlowNode actFlowNode : actFlowNodes) {
            if (FlowNodeTypeConstant.LINK_NODE.equals(actFlowNode.getNodeType())){
                List<ActFlowMultiNode> nodeLink = actFlowNode.getNodeLink();
                if (CollUtil.isNotEmpty(nodeLink)){
                    resultData.setTwoData(true);
                    for (ActFlowMultiNode actFlowMultiNode : nodeLink) {
                        if (VerifyConditionUtils.verifyConditionGroups(actFlowMultiNode.employConditionGroups(),formData)) {
                            resultData.setTwoData(false);
                            GenericReferenceEntity<List<ActFlowNode>, Boolean> executionStreamNodesForErrorResultEmpty = getExecutionStreamNodesForErrorResultEmpty(actFlowMultiNode.getNodes(), formData);
                            executionStreamNodes.addAll(executionStreamNodesForErrorResultEmpty.getOneData());
                            resultData.setTwoData(executionStreamNodesForErrorResultEmpty.getTwoData());
                        }
                    }
                }
            }else{
                executionStreamNodes.add(actFlowNode);
            }
        }
        if (resultData.getTwoData()){
            return new GenericReferenceEntity<>(new ArrayList<>(),true);
        }
        return resultData;
    }

    private Map<String,Map<String, Object>> queryVariableByExecutionId(Set<String> executionIds){
        if (CollUtil.isEmpty(executionIds)){
            return null;
        }
        List<HistoricVariableInstance> variableList = historyService.createHistoricVariableInstanceQuery().executionIds(executionIds).variableName(CommonConstant.FORM_DATA).list();
        if (CollUtil.isNotEmpty(variableList)){
            return variableList.stream().filter(item-> !CommonConstant.VARIABLE_TYPE_NULL.equals(item.getVariableTypeName())).collect(Collectors.toMap(HistoricVariableInstance::getProcessInstanceId, item -> (Map<String, Object>) item.getValue(), (v1, v2) -> v2));
        }
        return null;
    }

    private Map<String, String> queryDeploymentIdAndIconMap(Set<String> deploymentIds){
        List<ActFlowPublishConfigEntity> configurationList = actFlowPublishConfigurationMapper.selectList(new LambdaQueryWrapper<ActFlowPublishConfigEntity>().select(ActFlowPublishConfigEntity::getId, ActFlowPublishConfigEntity::getIconType,ActFlowPublishConfigEntity::getSummary).in(ActFlowPublishConfigEntity::getId, deploymentIds));
        Map<String, String> deploymentIdAndIcon = configurationList.stream().collect(Collectors.toMap(ActFlowPublishConfigEntity::getId, ActFlowPublishConfigEntity::getIconType, (k1, k2) -> k2));
        return deploymentIdAndIcon;
    }
    private Map<String, ActFlowPublishConfigEntity> queryDeploymentIdAndPublishMap(Set<String> deploymentIds){
        List<ActFlowPublishConfigEntity> configurationList = actFlowPublishConfigurationMapper.selectList(new LambdaQueryWrapper<ActFlowPublishConfigEntity>().select(ActFlowPublishConfigEntity::getId, ActFlowPublishConfigEntity::getIconType,ActFlowPublishConfigEntity::getSummary,ActFlowPublishConfigEntity::getManyConditionJson).in(ActFlowPublishConfigEntity::getId, deploymentIds));
        Map<String, ActFlowPublishConfigEntity> deploymentIdAndIcon = configurationList.stream().collect(Collectors.toMap(ActFlowPublishConfigEntity::getId, item->item, (k1, k2) -> k2));
        return deploymentIdAndIcon;
    }


    private Map<String, String> queryDefinitionIdAndProcessNameMap(Set<String> processDefinitionIds){
        if (processDefinitionIds.size() == 0){
            return null;
        }
        List<ProcessDefinition> processDefinitionList = repositoryService.createProcessDefinitionQuery().processDefinitionIds(processDefinitionIds).list();
        if(CollUtil.isNotEmpty(processDefinitionList)){
            return processDefinitionList.stream().collect(Collectors.toMap(ProcessDefinition::getId, ProcessDefinition::getName, (k1, k2) -> k2));
        }
        return null;
    }

    private Map<String, String> queryRunInstanceIdAndInitiatorMap(Set<String> processInstanceIds){
        if (processInstanceIds.size() == 0){
            return null;
        }
        List<ActFlowInitiatorAndInstanceIdEntity> initiatorAndInstanceIdList = actExtensionMapper.queryRunFlowInitiatorByInstanceIds(processInstanceIds);
        if (CollUtil.isNotEmpty(initiatorAndInstanceIdList)){
            Set<String> usernames = initiatorAndInstanceIdList.stream().map(ActFlowInitiatorAndInstanceIdEntity::getInitiator).collect(Collectors.toSet());
            Map<String, String> nickAndUserName = actUserService.queryUserByUsernames(usernames).stream().collect(Collectors.toMap(ActUser::getUsername, ActUser::getNickname, (k1, k2) -> k2));
            return initiatorAndInstanceIdList.stream().collect(Collectors.toMap(ActFlowInitiatorAndInstanceIdEntity::getInstanceId, item-> nickAndUserName.get(item.getInitiator()), (k1, k2) -> k2));
        }
        return null;
    }


    private Map<String, String> queryHiInstanceIdAndInitiatorMap(Set<String> processInstanceIds){
        if (processInstanceIds.size() == 0){
            return null;
        }
        List<ActFlowInitiatorAndInstanceIdEntity> initiatorAndInstanceIdList = actExtensionMapper.queryHiFlowInitiatorByInstanceIds(processInstanceIds);
        if (CollUtil.isNotEmpty(initiatorAndInstanceIdList)){
            Set<String> usernames = initiatorAndInstanceIdList.stream().map(ActFlowInitiatorAndInstanceIdEntity::getInitiator).collect(Collectors.toSet());
            Map<String, String> nickAndUserName = actUserService.queryUserByUsernames(usernames).stream().collect(Collectors.toMap(ActUser::getUsername, ActUser::getNickname, (k1, k2) -> k2));
            return initiatorAndInstanceIdList.stream().collect(Collectors.toMap(ActFlowInitiatorAndInstanceIdEntity::getInstanceId, item-> nickAndUserName.get(item.getInitiator()), (k1, k2) -> k2));
        }
        return null;
    }
}
